import util.FileConfigReader;
import util.FileReadingException;
import util.InvalidFileFormatException;
import EventPackage.Event;
import EventPackage.EventManagerInterface;
import EventPackage.EventQueue;
import InstrumentationPackage.Indicator;
import InstrumentationPackage.MessageWindow;


public class SecurityController {

	/**
	 * @param args
	 */
	public static void main(String args[])
	{
			String EvtMgrIP;					// Event Manager IP address
			Event Evt = null;					// Event object
			EventQueue eq = null;				// Message Queue
			EventManagerInterface em = null;	// Interface object to the event manager
			boolean windowAlarmState = false;	// Window alarm state: false == off, true == on
			boolean doorAlarmState = false;		// Door alarm state: false == off, true == on
			boolean motionAlarmState = false;	// Motion alarm state: false == off, true == on
			int	Delay = 2500;					// The loop delay (2.5 seconds)
			boolean Done = false;				// Loop termination flag
			int retry_interval = 0;
			int time_to_live = 0;

			if(args.length < 1 || args.length > 2){
	 			System.out.println("Wrong program initialization. Too many or too few arguments.\n The format should be:");
	 			System.out.println("<programName> <config_filename> (optional: <EventMngrIP>)");
	 			
	 			System.exit(0);
	 		}
	 		FileConfigReader config;
			try {
				config = new FileConfigReader(args[0]);
				retry_interval = config.getRetryInterval();
		 		time_to_live = config.getTtl();
		 		
			
			} catch (FileReadingException e1) {
				System.out.println("Error reading configuration file:"+e1.getMessage());
				e1.printStackTrace();
				System.exit(0);
			} catch (InvalidFileFormatException e1) {
				System.out.println("Error reading configuration file:"+e1.getMessage());
				e1.printStackTrace();
				System.exit(0);
			}
			/////////////////////////////////////////////////////////////////////////////////
			// Get the IP address of the event manager
			/////////////////////////////////////////////////////////////////////////////////
			
	 		if ( args.length == 1 )
	 		{
				// event manager is on the local system

				System.out.println("\n\n Attempting to register on the local machine..." );

				try
				{
					// Here we create an event manager interface object. This assumes
					// that the event manager is on the local machine

					em = new EventManagerInterface(retry_interval, time_to_live);
				}

				catch (Exception e)
				{
					System.out.println("Error instantiating event manager interface: " + e);

				} // catch

			} else {

				// event manager is not on the local system

				EvtMgrIP = args[1];

				System.out.println("\n\nAttempting to register on the machine:: " + EvtMgrIP );

				try
				{
					// Here we create an event manager interface object. This assumes
					// that the event manager is NOT on the local machine

					em = new EventManagerInterface(EvtMgrIP, retry_interval, time_to_live);
				}

				catch (Exception e)
				{
					System.out.println("Error instantiating event manager interface: " + e);

				} // catch

			} // if

			// Here we check to see if registration worked. If em is null then the
			// event manager interface was not properly created.

			if (em != null)
			{
				System.out.println("Registered with the event manager." );

				/* Now we create the humidity control status and message panel
				** We put this panel about 2/3s the way down the terminal, aligned to the left
				** of the terminal. The status indicators are placed directly under this panel
				*/

				float WinPosX = 0.0f; 	//This is the X position of the message window in terms 
										//of a percentage of the screen height
				float WinPosY = 0.60f;	//This is the Y position of the message window in terms 
									 	//of a percentage of the screen height 
				
				MessageWindow mw = new MessageWindow("Security Controller Status Console", WinPosX, WinPosY);
				
				// Now we put the indicators directly under the alarm status and control panel
				
				EventManagerInterface.setMessageWindow(mw); // Sends MessageWindow object to the EventManagerInterface instance
				
				Indicator windowInd = new Indicator ("Window Alarm OFF", mw.GetX(), mw.GetY()+mw.Height());
				Indicator doorInd = new Indicator ("Door Alarm OFF", mw.GetX()+(windowInd.Width()*2), mw.GetY()+mw.Height());
				Indicator motionInd = new Indicator ("Motion OFF", mw.GetX()+(doorInd.Width()*4), mw.GetY()+mw.Height());

				mw.WriteMessage("Registered with the event manager." );

		    	try
		    	{
					mw.WriteMessage("   Participant id: " + em.GetMyId() );
					mw.WriteMessage("   Registration Time: " + em.GetRegistrationTime() );

				} // try

		    	catch (Exception e)
				{
					System.out.println("Error:: " + e);

				} // catch

				/********************************************************************
				** Here we start the main simulation loop
				*********************************************************************/

				while ( !Done )
				{
					try
					{
						eq = em.GetEventQueue();

					} // try

					catch( Exception e )
					{
						mw.WriteMessage("Error getting event queue::" + e );

					} // catch

					// If there are messages in the queue, we read through them.
					// We are looking for EventIDs = 6, this is a request to turn the
					// window, doors or motion detection alarms on. Note that we get all the messages
					// at once... there is a 2.5 second delay between samples,.. so
					// the assumption is that there should only be a message at most.
					// If there are more, it is the last message that will effect the
					// output of the humidity as it would in reality.

					int qlen = eq.GetSize();

					for ( int i = 0; i < qlen; i++ )
					{
						Evt = eq.GetEvent();

						if ( Evt.GetEventId() == 6 )
						{
							if (Evt.GetMessage().equalsIgnoreCase("WINDOW1")) // Window alarm on
							{
								windowAlarmState = true;
								mw.WriteMessage("Received window alarm on event" );

							} // if

							if (Evt.GetMessage().equalsIgnoreCase("WINDOW0")) // Window alarm off
							{
								windowAlarmState = false;
								mw.WriteMessage("Received window alarm off event" );


							} // if

							if (Evt.GetMessage().equalsIgnoreCase("DOOR1")) // Door alarm on
							{
								doorAlarmState = true;
								mw.WriteMessage("Received Door alarm on" );


							} // if

							if (Evt.GetMessage().equalsIgnoreCase("DOOR0")) // Door alarm off
							{
								doorAlarmState = false;
								mw.WriteMessage("Received Door alarm off" );
							} // if
							
							
							if (Evt.GetMessage().equalsIgnoreCase("MOTION1")) // Motion alarm on
							{
								motionAlarmState = true;
								mw.WriteMessage("Received Motion alarm on" );
							} // if
							
							if (Evt.GetMessage().equalsIgnoreCase("MOTION0")) // Motion alarm off
							{
								motionAlarmState = false;
								mw.WriteMessage("Received Motion alarm off" );
							} // if

						} // if

						// If the event ID == 99 then this is a signal that the simulation
						// is to end. At this point, the loop termination flag is set to
						// true and this process unregisters from the event manager.

						if ( Evt.GetEventId() == 99 )
						{
							Done = true;

							try
							{
								em.UnRegister();

					    	} // try

					    	catch (Exception e)
					    	{
								mw.WriteMessage("Error unregistering: " + e);

					    	} // catch

					    	mw.WriteMessage( "\n\nSimulation Stopped. \n");

							// Get rid of the indicators. The message panel is left for the
							// user to exit so they can see the last message posted.

							windowInd.dispose();
							doorInd.dispose();
							motionInd.dispose();

						} // if

					} // for

					// Update the lamp status

					if (windowAlarmState)
					{
						// Set to red, window alarm is on

						windowInd.SetLampColorAndMessage("WIND ON", 3);

					} else {

						// Set to green, window alarm is off
						windowInd.SetLampColorAndMessage("WIND OFF", 0);

					} // if

					if (doorAlarmState)
					{
						// Set to red, door alarm is on

						doorInd.SetLampColorAndMessage("DOOR ON", 3);

					} else {

						// Set to green, door alarm is off

						doorInd.SetLampColorAndMessage("DOOR OFF", 0);

					} // if

					if (motionAlarmState)
					{
						// Set to red, motion alarm is on

						motionInd.SetLampColorAndMessage("MOTION ON", 3);

					} else {

						// Set to green, motion alarm is off

						motionInd.SetLampColorAndMessage("MOTION OFF", 0);

					} // if
					
					
					
					try
					{
						Thread.sleep( Delay );

					} // try

					catch( Exception e )
					{
						System.out.println( "Sleep error:: " + e );

					} // catch

				} // while

			} else {

				System.out.println("Unable to register with the event manager.\n\n" );

			} // if

		} // main


	 // HumidityControllers

}


